package core

import (
	"dgo/MyProj/PrjConf"
	"dgo/goutils/utils"
	"dgo/plg/plgbasev0"
	"fmt"
	"gitee.com/ymofen/supervalue"
	"time"
)

/**
  通知插件
*/

type ProjNotifyPlug struct {
	plgbasev0.ProjBaseProduce
	dna         int
	notifycnt   int
	replyOkFlag int
	replyTopic  string
	notifyTopic string
	ex          *plgbasev0.InnerEx
}

/*
**

	{
	  "id":"startup",
	  "type":"core.notify",
	  "conf":{
	     "input":{
	         "id":"", "templ":{}
	      },
	     "topic":"xxx",
	     "reply":""
	   }
	}
*/
func (this *ProjNotifyPlug) ReloadConf(conf *wrapper.SuperValue) error {
	isChanged := false
	this.ex.ReloadConf(conf.ValueByName("input"))
	if this.ex.ConfIsChanged() {
		isChanged = true
	}

	conf.CheckExistsStrFunc("reply", func(strv string) {
		if this.replyTopic != strv {
			this.replyTopic = strv
			this.ex.UnSubscribePre()
			this.ex.Subscribe(plgbasev0.ReplacePlaceholder(this.replyTopic), func(sender interface{}, channelid string, subscribeid interface{}, data interface{}, tag interface{}, isBreak *bool) bool {
				if json, ok := data.(*wrapper.SuperValue); ok {
					if json.IntByName("dna", -1) == this.dna {
						this.replyOkFlag = 1
						utils.Log.InfoTypef(this.PlugId, "响应OK:%s", json.AsJSONString(false))
					}
				}
				return true
			})
			isChanged = true
		}
	})

	conf.CheckExistsStrFunc("topic", func(strv string) {
		if this.notifyTopic != strv {
			this.notifyTopic = strv
			isChanged = true
		}
	})

	if isChanged {
		utils.Log.DebugTypef(this.PlugId, "changed")
	}

	if len(this.notifyTopic) > 0 {
		this.replyOkFlag = 0
		this.dna++
		dna := this.dna
		utils.AddTaskInterval(fmt.Sprintf("%s-%d", this.PlugId, this.PlugDNA), func() bool {
			topic := plgbasev0.ReplacePlaceholder(this.notifyTopic)
			this.ex.SendTopic(topic, func(json *wrapper.SuperValue) {
				this.notifycnt++
				json.SetKeyValues("plugid", this.PlugId, "dna", this.PlugDNA, "cnt", this.notifycnt, "uuid", PrjConf.APP_UUID)
			})
			if len(this.replyTopic) == 0 {
				return false // 没有响应主题只发一次
			}
			return this.replyOkFlag == 0 && this.dna == dna
		}, time.Second*30, time.Now().Add(time.Second*10))
	}

	return nil
}

func (this *ProjNotifyPlug) OnObjectNotify(sender interface{}, notifytype int, data interface{}) (rval interface{}, err error) {
	if notifytype == utils.NOTIFY_TYPE_SETCONF {
		if conf, ok := data.(*wrapper.SuperValue); ok {
			err = this.ReloadConf(conf)
		} else {
			err = fmt.Errorf("非法的JSON配置")
		}
	} else if notifytype == utils.NOTIFY_TYPE_RELEASE {
		this.ReleaseFlag = 1
		this.ex.Release()
	}
	return
}

func CreateProjNotifyPlugFunc(args ...interface{}) (rval interface{}, err error) {
	obj := &ProjNotifyPlug{}
	if len(args) > 0 {
		if str, ok := args[0].(string); ok {
			obj.PlugId = str
		}
	}
	obj.CheckDNA()
	obj.ex = plgbasev0.NewInnerEx()
	rval = obj
	return
}
